﻿// <copyright file="SpriteModel3D.cs" company="Axelerate Solutions S.A.">
// Copyright (c) Axelerate Solutions S.A.  All rights reserved.
// </copyright>

namespace Axelerate.Silverlight3D.Media.Media3D
{
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Collections.Generic;

    /// <summary>
    /// File name: SpriteModel3D.cs
    /// Company: Axelerate Solutions S.A.
    /// Created By: Daniel Rojas
    /// Created Date: 10/15/2008 10:30:00 h.
    /// Description: Allow manage 2D frameworkelements like Textblock on the 3D space. The 2D element is only located with respect to the 3D position but is not skew or scale, i need add the scale part.
    ///   <Modifications>
    ///   </Modifications>
    /// </summary>
    public sealed class SpriteModel3D : Model3D
    {
        #region Dependency Properties

        #region Point3D Position
        /// <summary>
        /// Gets or sets the position of the sprite on the 3D space
        /// </summary>
        public Point3D Position
        {
            get { return (Point3D)GetValue(PositionProperty); }
            set { SetValue(PositionProperty, value); }
        }

        /// <summary>
        ///  Using a DependencyProperty as the backing store for Positioin.  This enables animation, styling, binding, etc...
        /// </summary>
        public static readonly DependencyProperty PositionProperty =
            DependencyProperty.Register("Position", typeof(Point3D), typeof(SpriteModel3D), new PropertyMetadata(OnPositionPropertyChanged));

        /// <summary>
        /// Manage the on position property changed to raise the respective notifyPropertyChanged and mark the object as dirty.
        /// </summary>
        /// <param name="d">dependency object</param>
        /// <param name="e">event arguments of the property changed</param>
        private static void OnPositionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SpriteModel3D)d).NotifyPropertyChanged("Position");
            ((SpriteModel3D)d).IsDirty = true;
        }
        #endregion

        #region FrameworkElement Content

        public FrameworkElement Content
        {
            get { return (FrameworkElement)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Content.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ContentProperty =
            DependencyProperty.Register("Content", typeof(FrameworkElement), typeof(SpriteModel3D), new PropertyMetadata(OnContentPropertyChanged));

        private static void OnContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SpriteModel3D)d).NotifyPropertyChanged("Content");
            ((SpriteModel3D)d).IsDirty = true;
        }

        #endregion

        #endregion

        #region Methods
        
        /// <summary>
        /// Create a new instance of the SpriteModel3D (this class don't exist on WPF)
        /// </summary>
        public SpriteModel3D() : base()
        {
            this._cachedRenderEntities = new List<RenderEntity>();
        }
       
        internal override void CreateRenderEntities(RenderEntityPool entityPool)
        {
            if (this.Content != null)
            {
                entityPool.ReturnToPool(_cachedRenderEntities);
                _cachedRenderEntities.Clear();
                RenderEntity entity = entityPool.GetRenderEntity(null, 0, 0, 0, null, null);
                entity.Centroid = this.Position;
                entity.Visual = this.Content;
                entity.ZIndex = this.zIndexOverride;
                
                _cachedRenderEntities.Add(entity);
            }
        }

        /// <summary>
        /// Return the bounds of the sprite.
        /// The sprite in this moment is very dificult calculate his dimensions on the 3D Space, i go to try to fix it later.
        /// </summary>
        /// <returns>Rect3D with the posision and size of the model</returns>
        protected override Rect3D GetBounds()
        {
            return new Rect3D(this.Position, new Size3D(0,0,0));
        }

        #endregion

        
    }
}
